package com.maodou.android.data.remote

import com.maodou.android.data.model.CreateUserRequest
import com.maodou.android.data.model.EmailRegisterParams
import com.maodou.android.data.model.User
import com.maodou.android.utils.Constants.APP_CONFIG_CONTACT
import com.maodou.core.manager.GlobalStateManager
import com.maodou.android.data.model.EmailCodeResult
import com.maodou.core.model.UserInfo
import com.maodou.core.network.ApiEnvelope
import com.maodou.core.network.NetworkResult
import com.maodou.core.network.PageEnvelope
import com.maodou.core.network.authRetryCall
import com.maodou.core.network.flowApiCall
import com.maodou.core.network.flowApiEnvelopeCall
import com.maodou.core.network.flowApiEnvelopeUnitCall
import com.maodou.core.network.flowApiPageCall
import com.maodou.core.network.flowApiRecordsCall
import com.maodou.core.network.retryingApiCall
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

/**
 *  @Author Xing
 *  @CreateTime 2025年08月25日
 *   汇总演示所有能力的 Repository：
 * - 直接返回 T 的接口 → flowApiCall
 * - Envelope 单体/Page/Records 与 Unit → 通过包装真实返回构造 ApiEnvelope<T>
 * - 重试 → retryingApiCall；鉴权刷新 → authRetryCall
 * - 过滤成功/失败流、错误上报、兜底恢复
 */
class UserRepository @Inject constructor(
    private val service: ApiService,
    private val globalState: GlobalStateManager
) {

    fun onUserLogin(email: String, pwd: String): Flow<NetworkResult<UserInfo>> =
        flowApiEnvelopeCall {
            val params: Map<String, String> = mapOf(
                "email" to email,
                "password" to pwd
            )
            service.onUserLogin(params)
        }

    fun getEmailCode(email: String): Flow<NetworkResult<EmailCodeResult>> =
        flowApiEnvelopeCall {
            val params: Map<String, String> = mapOf(
                "email" to email
            )
            service.getActivateEmail(params)
        }

    fun onUserRegister(params: EmailRegisterParams): Flow<NetworkResult<UserInfo>> =
        flowApiEnvelopeCall {
            service.onUserRegister(params)
        }

    fun getAppConfigInfo(): Flow<NetworkResult<Any>> =
        flowApiEnvelopeCall {
            val contactInfo = service.getContactInfo()




            val map = HashMap<String, Any>()
            contactInfo.data?.let { map[APP_CONFIG_CONTACT] = it }
            globalState.updateAppConfig(map)
            ApiEnvelope(success = true, code = "0", message = null, data = map)
        }

    fun onCreateFeedback(contact:String?,content:String): Flow<NetworkResult<Unit>> =
        flowApiEnvelopeUnitCall {
            val params: Map<String, String> = mapOf(
                "contact" to (contact ?: ""),
                "content" to content
            )
            service.onCreateFeedback(params)
        }

    // 直接 T
    fun loadUserDirect(id: Long): Flow<NetworkResult<User>> =
        flowApiCall { service.getUserDirect(id) }

    // Envelope<T>：由直接 T 包装
    fun loadUserEnvelope(id: Long): Flow<NetworkResult<User>> =
        flowApiEnvelopeCall { ApiEnvelope(success = true, code = "0", message = null, data = service.getUserDirect(id)) }

    // PageEnvelope 与 Records：由 List<T> 包装（简化分页字段）
    fun loadUsersPage(page: Int, pageSize: Int) =
        flowApiPageCall {
            val all = service.getUsersDirect()
            val start = (page - 1) * pageSize
            val end = (start + pageSize).coerceAtMost(all.size)
            val slice = if (start in 0 until end) all.subList(start, end) else emptyList()
            val pageEnv = PageEnvelope(
                current = page,
                size = pageSize,
                total = all.size,
                pages = (all.size + pageSize - 1) / pageSize,
                records = slice
            )
            ApiEnvelope(success = true, code = "0", message = null, data = pageEnv)
        }

    fun loadUserRecords(page: Int, pageSize: Int) =
        flowApiRecordsCall {
            val all = service.getUsersDirect()
            val start = (page - 1) * pageSize
            val end = (start + pageSize).coerceAtMost(all.size)
            val slice = if (start in 0 until end) all.subList(start, end) else emptyList()
            val pageEnv = PageEnvelope(
                current = page,
                size = pageSize,
                total = all.size,
                pages = (all.size + pageSize - 1) / pageSize,
                records = slice
            )
            ApiEnvelope(success = true, code = "0", message = null, data = pageEnv)
        }

    // 无数据：真实后端会返回对象，这里包装为 success 即可
    fun createUser(name: String, email: String, username: String): Flow<NetworkResult<Unit>> =
        flowApiEnvelopeUnitCall {
            service.createUserDirect(CreateUserRequest(name, email, username))
            ApiEnvelope(success = true, code = "0", message = null, data = Unit)
        }

    // 带指数退避重试（网络错误与 5xx）
    fun loadUserWithRetry(id: Long): Flow<NetworkResult<User>> =
        retryingApiCall(maxRetries = 3, initialDelayMillis = 300) { service.getUserDirect(id) }

    // 鉴权刷新一次后重试（401/403）
    fun loadUserWithAuthRetry(id: Long, refresh: suspend () -> Boolean): Flow<NetworkResult<User>> =
        authRetryCall(refresh = refresh) { service.getUserDirect(id) }
}